package xiao_jin.fantastic_journey.core.handler;

import club.someoneice.cookie.event.Cancelable;
import club.someoneice.cookie.event.Event;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.FluidState;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

@SuppressWarnings("unused")
public abstract class LivingEntityEvent extends Event {
    public final LivingEntity entityLiving;

    protected LivingEntityEvent(LivingEntity entityLiving) {
        this.entityLiving = entityLiving;
    }

    /**
     * Fire when living entity before hurt.
     * This is a cancelable event. If it canceled, the living entity will miss the damage.
     *
     * @see LivingHurtEvent
     */
    @Cancelable
    public static class LivingDamagedEvent extends LivingEntityEvent {
        public final DamageSource source;

        public LivingDamagedEvent(LivingEntity entityLiving, DamageSource source) {
            super(entityLiving);
            this.source = source;
        }
    }

    /**
     * Fire when living entity after hurt.
     * This is a cancelable event. If it canceled, the living entity will have no hurt but still flicker.
     * The same as canceled is set the amount to 0.0f.
     *
     * @see LivingDamagedEvent
     */
    @Cancelable
    public static class LivingHurtEvent extends LivingEntityEvent {
        public final DamageSource source;
        private float amount;

        public LivingHurtEvent(LivingEntity entityLiving, DamageSource source, float amount) {
            super(entityLiving);
            this.source = source;
            this.amount = amount;
        }

        public float getAmount() {
            return this.amount;
        }

        public void setAmount(float value) {
            this.amount = value;
        }
    }

    /**
     * On living entity swim in fluid, this event will fire.
     * This is not cancelable event, and callback the JumpingCooldown as Integer.
     */
    public static class LivingSwimUpawrdEvent extends LivingEntityEvent {
        public final World world;
        public final BlockPos pos;
        public final FluidState fluid;
        public final TagKey<Fluid> fluidTag;

        private int jumpingCooldown;

        public LivingSwimUpawrdEvent(LivingEntity entityLiving, World world, BlockPos pos, FluidState fluid, TagKey<Fluid> fluidTag, int jumpingCooldown) {
            super(entityLiving);
            this.world = world;
            this.pos = pos;
            this.fluid = fluid;
            this.fluidTag = fluidTag;
            this.jumpingCooldown = jumpingCooldown;
        }

        public int getJumpingCooldown() {
            return jumpingCooldown;
        }

        public void setJumpingCooldown(int jumpingCooldown) {
            this.jumpingCooldown = jumpingCooldown;
        }
    }

    @Cancelable
    public static class LivingJumpingEvent extends LivingEntityEvent {
        public final World world;

        public LivingJumpingEvent(LivingEntity entityLiving, World world) {
            super(entityLiving);
            this.world = world;
        }
    }
}
